package com.yuyou.tas.report.service.impl;

import com.yuyou.tas.report.entity.ExamModelBlock;
import com.yuyou.tas.report.mapper.*;
import com.yuyou.tas.report.service.IExamModelService;
import com.yuyou.tas.report.vo.req.*;
import com.yuyou.tas.report.vo.resp.*;
import com.yuyou.tas.service.api.admin.entity.AuthUser;
import com.yuyou.tas.service.api.admin.entity.CommDataConfig;
import com.yuyou.tas.service.api.admin.service.AuthUserAPI;
import com.yuyou.tas.service.api.lesson.dto.LessonClassPageDTO;
import com.yuyou.tas.service.api.lesson.entity.*;
import com.yuyou.tas.service.api.lesson.service.BaseDataAPI;
import com.yuyou.tas.service.api.lesson.service.CommDataConfigAPI;
import com.yuyou.tas.service.api.lesson.service.LessonAPI;
import com.yuyou.tas.service.api.lesson.service.LessonClassAPI;
import com.yuyou.tas.service.api.report.dto.ExamModelDTO;
import com.yuyou.tas.service.api.report.dto.ExamModelVo;
import com.yuyou.tas.service.api.report.entity.ExamModel;
import com.yuyou.tas.service.api.report.entity.ExamModelActivity;
import com.yuyou.tas.service.api.report.entity.ExamModelQues;
import com.yuyou.tas.service.api.report.entity.ExamModelRange;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.PageParams;
import com.yuyou.tas.util.bean.Pagination;
import com.yuyou.tas.util.bean.ResBoolSimpleInfo;
import com.yuyou.tas.util.enums.admin.AuthUserEnums;
import com.yuyou.tas.util.enums.admin.CommDataConfigEnums;
import com.yuyou.tas.util.enums.lesson.LessonClassEnums;
import com.yuyou.tas.util.enums.report.ExamModelEnums;
import com.yuyou.tas.util.exception.BusinessException;
import com.yuyou.tas.util.message.report.ExamModelMess;
import com.yuyou.tas.util.tool.*;
import javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by yujin.liu on 2018/9/20.
 */
@Service
public class ExamModelServiceImpl implements IExamModelService{

    @Autowired
    private ExamModelMapper examModelMapper;

    @Autowired
    private ExamModelQuesMapper examModelQuesMapper;

    @Autowired
    private ExamModelRangeMapper examModelRangeMapper;

    @Autowired
    private ExamModelBlockMapper examModelBlockMapper;

    @Autowired
    private BaseDataAPI baseDataAPI;

    @Autowired
    private CommDataConfigAPI commDataConfigAPI;

    @Autowired
    private LessonClassAPI lessonClassAPI;

    @Autowired
    private LessonAPI lessonAPI;

    @Autowired
    private ExamModelActivityMapper examModelActivityMapper;

    @Autowired
    private ExamModelReportMapper examModelReportMapper;

    @Autowired
    private ExamModelReportQuesMapper examModelReportQuesMapper;

    @Autowired
    private AuthUserAPI authUserAPI;


    @Override
    @Transactional(rollbackFor=Exception.class)
    public void saveExamImport(Long organId, List<ExamExcel> examExcelList) throws Exception {
        // `auth_organization_id`,`data_subject`,`wal`,`base_section_id`,`base_trimester_id`,`data_time_type`,`base_level_id`,`range_type` 确定唯一标准模板


        List<CommDataConfig> subjectList = commDataConfigAPI.findUseByCategory(CommDataConfigEnums.category.subject.getValue());
        List<CommDataConfig> timeTypeList = commDataConfigAPI.findUseByCategory(CommDataConfigEnums.category.timeType.getValue());
        List<CommDataConfig> questionTypeList = commDataConfigAPI.findUseByCategory(CommDataConfigEnums.category.questionType.getValue());

        // 年级
        Map<String, Object> condition = new HashMap<>();
        List<BaseSection> sectionList = baseDataAPI.findSectionName(condition);

        // 期数
        List<BaseTrimester> trimesterList = baseDataAPI.findTrimByOran(organId);

        // 班型
        List<BaseLevel> baseLeveList = baseDataAPI.findBaseLevelByOrganId(organId);

        // 校区
        List<BaseSchool> baseSchoolList = baseDataAPI.getSchoolByOrganId(organId);

        Map<String, CommDataConfig> subjectMap = BeanUtils.toMap(subjectList, "name");
        Map<String, CommDataConfig> timeTypeMap = BeanUtils.toMap(timeTypeList, "name");
        Map<String, CommDataConfig> questionTypeMap = BeanUtils.toMap(questionTypeList, "name");
        Map<String, BaseSection> sectionMap = BeanUtils.toMap(sectionList, "name");
        Map<String, BaseTrimester> trimesterMap = BeanUtils.toMap(trimesterList, "name");
        Map<String, BaseLevel> baseLevelMap = BeanUtils.toMap(baseLeveList, "name");
        Map<String, BaseSchool> baseSchoolMap = BeanUtils.toMap(baseSchoolList, "name");

        Long examModeIdTemp = null;
        List<Long> examModeIdList = new ArrayList<>();
        for(ExamExcel examExcel : examExcelList){
            // 先导入试卷模版
            if(null != examExcel.getExamName()) {
                ExamModel examModel = new ExamModel();
                examModel.setId(Sequence.getSequence().nextId());
                examModel.setAuthOrganizationId(organId);
                examModel.setNum(UUIDUtil.getUUID());
                examModel.setWal(StringUtils.isEmpty(examExcel.getSubjectType()) ? 0 : ("文科".equals(examExcel.getSubjectType()) ? 1 : 2));
                examModel.setName(examExcel.getExamName());
                examModel.setDataSubject(subjectMap.get(examExcel.getSubject()).getId());
                examModel.setBaseSectionId(sectionMap.get(examExcel.getSection()).getId());
                examModel.setBaseTrimesterId(trimesterMap.get(examExcel.getTrimester()).getId());
                examModel.setDataTimeType(timeTypeMap.get(examExcel.getTimeType()).getId());
                examModel.setRangeType(examExcel.getRangeType().equals("标准") ? ExamModelEnums.rangeType.stand.getValue() : ExamModelEnums.rangeType.defind.getValue());
                if(examModel.getRangeType().equals(ExamModelEnums.rangeType.stand.getValue())){
                    examModel.setBaseLevelId(Long.valueOf(baseLevelMap.get(examExcel.getBaseLevel()).getCode()));
                }
                examModel.setpStatus(ExamModelEnums.pStatus.ed.getValue());
                examModel.setScore(examExcel.getTotalScore());
                examModel.setpTime(DateUtil.now());
                examModel.setCreateTime(DateUtil.now());
                examModel.setUpdateTime(DateUtil.now());

                examModelMapper.insert(examModel);
                examModeIdList.add(examModel.getId());

                examModeIdTemp = examModel.getId();
            }

            // 导入班级
            List<Long> classIdList = new ArrayList<>();
            if(!StringUtils.isEmpty(examExcel.getClassName())){
                List<String> classNameList = Arrays.asList(examExcel.getClassName().split(","));
                for(String className : classNameList){
                    // 查找班级
                    Pagination<LessonClassPageDTO> queryPgn = new Pagination<>();
                    PageParams pageParams = new PageParams();
                    pageParams.setPageIndex(1);
                    pageParams.setPageSize(10);
                    Map<String, Object> conditions =new HashMap<>();
                    conditions.put("dataSubject", subjectMap.get(examExcel.getSubject()).getId());
                    conditions.put("baseSectionId", sectionMap.get(examExcel.getSection()).getId());
                    conditions.put("baseTrimesterId", trimesterMap.get(examExcel.getTrimester()).getId());
                    conditions.put("baseLevelId", baseLevelMap.get(examExcel.getBaseLevel()).getCode());
                    conditions.put("schoolId", baseSchoolMap.get(examExcel.getSchool()).getId());
                    conditions.put("name", className);
                    queryPgn.setPageParams(pageParams);
                    queryPgn.setConditions(conditions);
                    int total = lessonClassAPI.findLessonClassPageCount(queryPgn);
                    queryPgn.setTotal(total);
                    queryPgn.toBePage();
                    List<LessonClassPageDTO> lessonClassPageList = lessonClassAPI.findLessonClassPageList(queryPgn);
                    if(CollectionUtils.isEmpty(lessonClassPageList)){
                        throw new NotFoundException("找不到班级");
                    }
                    for(LessonClassPageDTO lessonClassPageDTO : lessonClassPageList){
                        classIdList.add(lessonClassPageDTO.getId());
                    }
                }
                // 模版班级范围
                if(!CollectionUtils.isEmpty(classIdList)){
                    for(Long classId : classIdList){
                        ExamModelRange examModelRange = new ExamModelRange();
                        examModelRange.setId(Sequence.getSequence().nextId());
                        examModelRange.setAuthOrganizationId(organId);
                        examModelRange.setExamModelId(examModeIdTemp);
                        examModelRange.setLessonClassId(classId);
                        examModelRange.setCreateTime(DateUtil.now());
                        examModelRangeMapper.insert(examModelRange);
                    }
                }
            }
        }

        // 模块题目
        for(Long exammModelId : examModeIdList){
            for(ExamExcel examExcel : examExcelList){
                ExamModelQues examModelQues = new ExamModelQues();
                examModelQues.setId(Sequence.getSequence().nextId());
                examModelQues.setExamModelId(exammModelId);
                examModelQues.setName(examExcel.getQuestionName());
                examModelQues.setSort(examExcel.getSort());
                examModelQues.setDataQuestionType(questionTypeMap.get(examExcel.getQuestionType()).getId());
                examModelQues.setScore(examExcel.getScore());
                examModelQues.setHard(examExcel.getHard());
                examModelQues.setKnowledgeD(examExcel.getKnowledgeD());
                examModelQues.setKnowledgeI(examExcel.getKnowledgeI());
                examModelQues.setCreateTime(DateUtil.now());

                examModelQuesMapper.insert(examModelQues);
            }
        }
    }

    @Override
    public List<ExamModelVo> selectByOrganId(Long organId) {
        return examModelMapper.selectByOrganId(organId);
    }

    @Override
    public List<ExamModelQues> selectQuesByOrganId(Long organId) {
        return examModelQuesMapper.selectByOrganId(organId);
    }

	@Override
	public ExamModel selectByPrimaryKey(Long id) {
		return examModelMapper.selectByPrimaryKey(id);
	}

    @Override
    public List<ExamModel> selectModelByTrimester(Long trimesterId) {
        return examModelMapper.selectModelByTrimester(trimesterId);
    }

    @Override
    public List<ExamModel> selectModelByLevel(Long levelId) {
        return examModelMapper.selectModelByLevel(levelId);
    }

    @Override
    public int findExamModelCount(Pagination<ExamModelDTO> queryPgn) {
        return examModelMapper.findExamModelCount(queryPgn);
    }

    @Override
    public List<ExamModelDTO> findExamModelPageList(Pagination<ExamModelDTO> queryPgn) {
        return examModelMapper.findExamModelPageList(queryPgn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteExamModelById(Long id) {
        examModelMapper.deleteByPrimaryKey(id);
        examModelQuesMapper.deleteByExamModelId(id);
        examModelRangeMapper.deleteByExamModelId(id);
        examModelReportMapper.deleteReportByModelId(id);
        examModelReportQuesMapper.deleteReportQuesByModelId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResBoolSimpleInfo addExamModel(ExamModelAdd examModelAdd, LoginRedisObj loginObj) {
        if(ExamModelEnums.rangeType.stand.getValue() == examModelAdd.getRangeType()){
            List<ExamModel> examModelQuery = examModelMapper.findModelByActivitySubjectWalSectionTrimesterLevelTimetype(examModelAdd.getExamModelActivityId(), examModelAdd.getDataSubject(), examModelAdd.getWal(),
                    examModelAdd.getBaseSectionId(), examModelAdd.getBaseTrimesterId(), examModelAdd.getBaseLevelId(), examModelAdd.getDataTimeType(), ExamModelEnums.rangeType.stand.getValue());
            if(!CollectionUtils.isEmpty(examModelQuery)) {
                return new ResBoolSimpleInfo(false, "本活动中模板已经存在");
            }
        }
        
        if(examModelAdd.getRangeType().intValue()==ExamModelEnums.rangeType.stand.getValue()
        		&& examModelAdd.getBaseLevelId()==null){
        	return new ResBoolSimpleInfo(false, "班型不能为空");
        }
        
        ExamModel examModel = new ExamModel();
        DefindBeanUtils.copyProperties(examModelAdd, examModel);
        examModel.setId(Sequence.getSequence().nextId());
        examModel.setNum(UUIDUtil.getUUID());
        examModel.setAuthOrganizationId(loginObj.getOrganizationId());
        examModel.setScore(new BigDecimal(0));
        examModel.setCreateUser(loginObj.getUserId());
        examModel.setCreateTime(DateUtil.now());
        examModel.setUpdateTime(DateUtil.now());
        examModelMapper.insert(examModel);
        
        //自定义没有班型
        if(examModel.getRangeType().intValue()==ExamModelEnums.rangeType.defind.getValue()){
        	 examModelMapper.clearBaseLevel(examModel.getId());
        }
        

        // 引用模板需要复制模块和题目
        if(null != examModelAdd.getpId()){
            List<ExamModelBlock> examModelBlockList = examModelBlockMapper.findBlockByExamModelId(examModelAdd.getpId());
            List<ExamModelQues> examModelQuesList = examModelQuesMapper.getByModelId(examModelAdd.getpId());
            Map<Long, List<ExamModelQues>> examModelQuesGroup = BeanUtils.toGroup(examModelQuesList, "examModelBlockId");
            ExamModelBlock examModelBlock = new ExamModelBlock();
            BigDecimal[] totalScore = {new BigDecimal(0)};  // 模板总分
            examModelBlockList.forEach(b -> {
                examModelBlock.setId(Sequence.getSequence().nextId());
                examModelBlock.setExamModelId(examModel.getId());
                examModelBlock.setDataQuestionType(b.getDataQuestionType());
                examModelBlock.setName(b.getName());
                examModelBlock.setSort(b.getSort());
                examModelBlock.setCreateTime(DateUtil.now());
                examModelBlockMapper.insert(examModelBlock);

                List<ExamModelQues> examModelQueOfBlockList = examModelQuesGroup.get(b.getId());
                if(!CollectionUtils.isEmpty(examModelQueOfBlockList)){
                    ExamModelQues examModelQues = new ExamModelQues();
                    examModelQueOfBlockList.forEach(q -> {
                        DefindBeanUtils.copyProperties( q , examModelQues);
                        examModelQues.setId(Sequence.getSequence().nextId());
                        examModelQues.setExamModelId(examModel.getId());
                        examModelQues.setExamModelBlockId(examModelBlock.getId());
                        examModelQues.setCreateTime(DateUtil.now());
                        examModelQuesMapper.insert(examModelQues);

                        totalScore[0] = totalScore[0].add(q.getScore());
                    });
                }
            });
            // 更新模板总分
            ExamModel examModelUpdate = new ExamModel();
            examModelUpdate.setId(examModel.getId());
            examModelUpdate.setScore(totalScore[0]);
            examModelMapper.updateByPrimaryKeySelective(examModelUpdate);

        }
        return new ResBoolSimpleInfo(true, "OK", examModel);
    }

    @Override
    public ExamModelDetailVo detailExamModel(Long examModelId, LoginRedisObj loginObj) {
        ExamModelDetailVo examModelDetailVo = new ExamModelDetailVo();
        ExamModel examModel = examModelMapper.selectByPrimaryKey(examModelId);
        DefindBeanUtils.copyProperties(examModel, examModelDetailVo);
        examModelDetailVo.setCreateUserId(examModel.getCreateUser());
        if(ExamModelEnums.rangeType.defind.getValue() == examModel.getRangeType()){
            examModelDetailVo.setLessonClassList(examModelRangeMapper.findLessonClassIdsByExamModelId(examModelId, loginObj.getUserId()));
        }

        return examModelDetailVo;
    }

    @Override
    public ResBoolSimpleInfo<String> editExamModel(ExamModelEdit examModelEdit, LoginRedisObj loginObj) {
        ExamModel oldOne = this.selectByPrimaryKey(examModelEdit.getId());
        if(oldOne == null){
            return new ResBoolSimpleInfo(false, ExamModelMess.MODEL_NULL);
        }
        // 模板已经有报告，不能编辑
        if(examModelReportMapper.countReportByModelId(examModelEdit.getId()) > 0){
            return new ResBoolSimpleInfo(false, ExamModelMess.MODEL_REPORT_EXIST);
        }
        
        if(examModelEdit.getRangeType().intValue()==ExamModelEnums.rangeType.stand.getValue()
        		&& examModelEdit.getBaseLevelId()==null){
            return new ResBoolSimpleInfo(false, ExamModelMess.MODEL_STAND_BASE_LEVEL);
        }

        //自定义类型换成标准类型去掉绑定适用范围
        if(examModelEdit.getRangeType().intValue()==ExamModelEnums.rangeType.stand.getValue()
                && oldOne.getRangeType().intValue() == ExamModelEnums.rangeType.defind.getValue()){
            examModelRangeMapper.deleteByExamModelId(examModelEdit.getId());
        }

        /*if(examModelRangeMapper.countByExamModelId(examModelEdit.getId()) > 0){
            return new ResBoolSimpleInfo(false, ExamModelMess.MODEL_RANGE_EXIST);
        }*/
        
        ExamModel examModel = new ExamModel();
        DefindBeanUtils.copyProperties(examModelEdit, examModel);
        examModel.setScore(null);
        examModel.setUpdateTime(DateUtil.now());
        examModel.setUpdateUser(loginObj.getUserId());
        examModelMapper.updateByPrimaryKeySelective(examModel);
        //自定义没有班型
        if(examModel.getRangeType().intValue()==ExamModelEnums.rangeType.defind.getValue()){
        	 examModelMapper.clearBaseLevel(examModel.getId());
        }
        return new ResBoolSimpleInfo(true, "OK");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResBoolSimpleInfo<String> addLessonClass2ExamModel(Long examModelId, List<Long> lessonClassIds, LoginRedisObj loginObj){

        ExamModel examModel = examModelMapper.selectByPrimaryKey(examModelId);
        if(null == examModel){
            return new ResBoolSimpleInfo<>(false,"试卷模板不存在");
        }
        if(0 == examModel.getRangeType()){
            return new ResBoolSimpleInfo<>(false,"标准模板不能添加班级");
        }

        // 管理员操作
        if(AuthUserEnums.isManage.yes.getValue().equals(loginObj.getIsManager())){
            examModelRangeMapper.deleteByCreateUserAndNotInClassIds(examModelId, loginObj.getUserId(), lessonClassIds);
        }else{
            examModelRangeMapper.deleteByExamModelIdCreateUser(examModelId, loginObj.getUserId());
        }

        // 不是当前用户的数据不再插入
        List<LessonClassPageDTO> lessonClassListOfModel = examModelRangeMapper.findLessonClassIdsByExamModelId(examModelId, loginObj.getUserId());
        if(!CollectionUtils.isEmpty(lessonClassListOfModel)){
            List<Long> existClassIds = BeanUtils.toList(lessonClassListOfModel, "id");
            lessonClassIds.removeAll(existClassIds);
        }

        // 教师或教研需要去掉没有权限的班级
        AuthUser authUser = authUserAPI.selectById(loginObj.getUserId());
        if(null != authUser.getType() &&(AuthUserEnums.type.teacher.getValue() == authUser.getType() || AuthUserEnums.type.teaching.getValue() == authUser.getType())){
            List<LessonClassUserRel> lessonClassUserRelList = lessonClassAPI.findByUserId(loginObj.getUserId());
            List<Long> lessonClassUserRelIds = BeanUtils.toList(lessonClassUserRelList, "lessonClassId");
            lessonClassIds.retainAll(lessonClassUserRelIds);
        }

        // 去掉已作废的班
        if(!CollectionUtils.isEmpty(lessonClassIds)){
            List<LessonClass> lessonClassQuery = lessonClassAPI.findByClassIdsAndClassStatus(lessonClassIds, LessonClassEnums.classStatus.cancel.getValue());
            if(!CollectionUtils.isEmpty(lessonClassQuery)){
                List<Long> classIds = BeanUtils.toList(lessonClassQuery, "id");
                lessonClassIds.removeAll(classIds);
            }
        }


        // 插入模板班级
        for(Long lessonClassId : lessonClassIds){
            ExamModelRange examModelRange = new ExamModelRange();
            examModelRange.setId(Sequence.getSequence().nextId());
            examModelRange.setAuthOrganizationId(loginObj.getOrganizationId());
            examModelRange.setLessonClassId(lessonClassId);
            examModelRange.setExamModelId(examModelId);
            examModelRange.setCreateTime(DateUtil.now());
            examModelRange.setCreateUser(loginObj.getUserId());
            examModelRangeMapper.insert(examModelRange);
        }

        return new ResBoolSimpleInfo<>(true ,"");
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResBoolSimpleInfo addBlock2ExamModel(Long examModelId, List<ExamModelBlockVo> examModelBlockVoList){
        if(examModelReportMapper.countReportByModelId(examModelId) > 0){
            return new ResBoolSimpleInfo(false, "模板已经录分，不能编辑");
        }
        // 先删除
        examModelBlockMapper.deleteByExamModelId(examModelId);
        examModelQuesMapper.deleteByExamModelId(examModelId);

        ExamModelBlock examModelBlock = new ExamModelBlock();
        BigDecimal totalScore = new BigDecimal(0);  // 模板总分
        for(ExamModelBlockVo examModelBlockVo : examModelBlockVoList){
            DefindBeanUtils.copyProperties(examModelBlockVo, examModelBlock);
            examModelBlock.setId(Sequence.getSequence().nextId());
            examModelBlock.setExamModelId(examModelId);
            examModelBlock.setCreateTime(DateUtil.now());
            // 试卷模块添加
            examModelBlockMapper.insert(examModelBlock);
            // 模块题目添加
            for(ExamModelQues examModelQues : examModelBlockVo.getExamModelQuesList()){
                examModelQues.setId(Sequence.getSequence().nextId());
                examModelQues.setExamModelId(examModelId);
                examModelQues.setExamModelBlockId(examModelBlock.getId());
                examModelQues.setCreateTime(DateUtil.now());
                examModelQues.setScore(examModelQues.getScore().abs());//取绝对值

                //处理题目知识点
                if(!StringUtils.isEmpty(examModelQues.getKnowledgeI())){
                    String[] arr = examModelQues.getKnowledgeI().trim().replaceAll("；",";").split(";");
                    Set<String> knowsSet = new HashSet<>(Arrays.asList(arr));
                    String knowledges = "";
                    for (String s :
                            knowsSet) {
                        if(!StringUtils.isEmpty(s)){
                            knowledges =  knowledges + s + ";";
                        }
                    }
                    if(!StringUtils.isEmpty(knowledges)){
                        examModelQues.setKnowledgeI(knowledges.substring(0, knowledges.length() -1));
                    }else {
                        throw new BusinessException("第" + examModelQues.getName() + "题请填写正确的知识点，多个用;号隔开。");
                    }
                }

                examModelQuesMapper.insert(examModelQues);

                totalScore = totalScore.add(examModelQues.getScore());
            }
        }
        // 更新模板总分
        ExamModel examModel = new ExamModel();
        examModel.setId(examModelId);
        examModel.setScore(totalScore);
        examModelMapper.updateByPrimaryKeySelective(examModel);

        return new ResBoolSimpleInfo(true, "ok");
    }

    @Override
    public List<ExamModelBlockVo> examModelBlockList(Long examModelId){

        List<ExamModelBlockVo> examModelBlockVoList = new ArrayList<>();
        // 查找模板的模块
        List<ExamModelBlock> examModelBlockList = examModelBlockMapper.findBlockByExamModelId(examModelId);
        if(CollectionUtils.isEmpty(examModelBlockList)){
            return examModelBlockVoList;
        }
        List<Long> examModelBlockIds = BeanUtils.toList(examModelBlockList, "id");
        //查找模板的问题
        List<ExamModelQues> examModelQuesList = examModelQuesMapper.findQuesByExamModelBlockIds(examModelBlockIds);
        Map<Long, List<ExamModelQues>> examModelQuesGroup = BeanUtils.toGroup(examModelQuesList, "examModelBlockId");
        for(ExamModelBlock examModelBlock : examModelBlockList){
            ExamModelBlockVo examModelBlockVo = new ExamModelBlockVo();
            DefindBeanUtils.copyProperties(examModelBlock, examModelBlockVo);
            examModelBlockVo.setExamModelQuesList(examModelQuesGroup.get(examModelBlock.getId()));
            examModelBlockVoList.add(examModelBlockVo);
        }
        return examModelBlockVoList;
    }

    @Override
    public List<ExamModelSimpleVo> classExamModelList(Long classId, Long organId ,Long levelId, Integer range_type , Integer type , Long activityId) throws Exception {
        List<ExamModelSimpleVo> list = new ArrayList<>();
        LessonClass lessonClass = lessonClassAPI.findLessonClassByClassId(classId);
        if(lessonClass != null && lessonClass.getLessonId() != null){
            Lesson lesson = lessonAPI.getById(lessonClass.getLessonId());
            if(lesson != null){

                //获取系统预置部分
                List<ExamModelSimpleVo> stands = new ArrayList<>();
                List<ExamModelSimpleVo> definds = new ArrayList<>();
                //获取符合的标准试卷列表-搜索其他班型,或者自定义类型试卷时不查询
                if((levelId == null || levelId.equals(lesson.getBaseLevelId())) && (range_type == null || ExamModelEnums.rangeType.stand.getValue() == range_type)){
                    stands = examModelMapper.findStandByParams(lesson.getDataSubject() , lesson.getBaseLevelId() , lesson.getBaseSectionId() , lessonClass.getBaseTrimesterId() , organId ,classId , type,activityId);
                }
                //获取班级下的自定义试卷列表-搜索标准类型时不查询
                if(range_type == null || ExamModelEnums.rangeType.defind.getValue() == range_type){
                    definds = examModelMapper.findDefindByClassId(classId , organId , type , levelId,activityId);
                }
                if(CollectionUtils.isEmpty(definds)){//没有自定义
                    list.addAll(stands);
                }else{//存在自定义，过滤掉标准中相同期类型和文理科
                    Map<String , ExamModelSimpleVo>  map = BeanUtils.toMap(definds , "val");
                    list.addAll(stands.stream().filter(stand -> !map.containsKey(stand.getWal()+"-"+stand.getTimeType())).collect(Collectors.toList()));
                    list.addAll(definds);
                }


                //获取其他模板
                List<ExamModelSimpleVo> others = new ArrayList<>();
                //其他的标准模板
                List<ExamModelSimpleVo> others_s = examModelMapper.findOtherStanByParams(lesson.getDataSubject() ,
                        levelId ,
                        lesson.getBaseSectionId() ,
                        lessonClass.getBaseTrimesterId() ,
                        organId ,classId , type ,range_type,activityId);

                //其他的自定义模板-不按班型筛选
                List<ExamModelSimpleVo> others_d = examModelMapper.findOtherDefindByParams(lesson.getDataSubject() ,
                        lesson.getBaseSectionId() ,
                        lessonClass.getBaseTrimesterId() ,
                        organId ,classId , type ,range_type,activityId);

                if(!CollectionUtils.isEmpty(others_s)){
                    others.addAll(others_s);
                }
                if(!CollectionUtils.isEmpty(others_d)){
                    others.addAll(others_d);
                }


                if(!CollectionUtils.isEmpty(others)){
                    Map<Long , ExamModelSimpleVo> list_map = BeanUtils.toMap(list , "id");
                    List<ExamModelSimpleVo> other_filted = others.stream().filter(other -> !list_map.containsKey(other.getId())).collect(Collectors.toList());
                    other_filted.forEach(examModelSimpleVo -> {if(examModelSimpleVo.getRecordNum() > 0){examModelSimpleVo.setExamType(1);}});
                    list.addAll(other_filted.stream().filter(other -> other.getExamType() == 1).collect(Collectors.toList()));//自选
                    list.addAll(other_filted.stream().filter(other -> other.getExamType() == 2).collect(Collectors.toList()));//其他
                }
            }
        }
        return list;
    }

    @Override
    public int findExamModelActivityCount(Pagination<ExamModelActivity> queryPgn) {
        return examModelActivityMapper.findExamModelActivityCount(queryPgn);
    }

    @Override
    public List<ExamModelActivity> findExamModelActivityPageList(Pagination<ExamModelActivity> queryPgn) {
        return examModelActivityMapper.findExamModelActivityPageList(queryPgn);
    }

    @Override
    public ExamModelActivity addExamModelActivity(ExamModelActivityAdd examModelActivityAdd, LoginRedisObj loginObj) {

        ExamModelActivity examModelActivity = new ExamModelActivity();
        DefindBeanUtils.copyProperties(examModelActivityAdd, examModelActivity);
        examModelActivity.setId(Sequence.getSequence().nextId());
        examModelActivity.setAuthOrganizationId(loginObj.getOrganizationId());
        examModelActivity.setCreateUser(loginObj.getUserId());
        examModelActivity.setCreateTime(DateUtil.now());
        examModelActivity.setUpdateTime(DateUtil.now());
        examModelActivityMapper.insert(examModelActivity);
        return examModelActivity;
    }

    @Override
    public void editExamModelActivity(ExamModelActivityEdit examModelActivityEdit, LoginRedisObj loginObj) {
        ExamModelActivity examModelActivity = new ExamModelActivity();
        DefindBeanUtils.copyProperties(examModelActivityEdit, examModelActivity);
        examModelActivity.setUpdateTime(DateUtil.now());
        examModelActivity.setUpdateUser(loginObj.getUserId());
        examModelActivityMapper.updateByPrimaryKeySelective(examModelActivity);
    }

    @Override
    public StudentRecordVo detailExamModelChange(Long examId , Long stuId) {
        StudentRecordVo s = new StudentRecordVo();
        List<ExamModelBlockRecordVo> list = new ArrayList<>();
        List<ExamModelBlock> blocks = examModelBlockMapper.findBlockByExamModelId(examId);
        
        ExamModel examModel=examModelMapper.selectByPrimaryKey(examId);
        if(examModel!=null){
            s.setModelId(examModel.getId());
            s.setModelName(examModel.getName());
            s.setModelScore(examModel.getScore());
        }
      
        //模版下学生录分记录
        List<QuesRecordVo> quesRecordVos = examModelReportQuesMapper.getStuQues(null , examId , stuId);
        if(!CollectionUtils.isEmpty(quesRecordVos)){
            Map<Long , List<QuesRecordVo>> r_map = BeanUtils.toGroup(quesRecordVos , "examModelBlockId");
            blocks.forEach(b -> {
                ExamModelBlockRecordVo blockRecordVo = new ExamModelBlockRecordVo();
                DefindBeanUtils.copyProperties(b , blockRecordVo);
                blockRecordVo.setList(r_map.get(b.getId()));
                list.add(blockRecordVo);
            });
            s.setRecordStatus(1);
            s.setStatus(quesRecordVos.get(0).getStatus());
        }else{//该学生在该模版还没有录分
            //试卷题目列表
            List<ExamModelQues> quesList = examModelQuesMapper.getByModelId(examId);
            List<QuesRecordVo> defaultList= new ArrayList<>();
            quesList.forEach(ques -> {
                QuesRecordVo q = new QuesRecordVo();
                DefindBeanUtils.copyProperties(ques , q);
                q.setGetScore(BigDecimal.ZERO);
                q.setQuesId(ques.getId());
                defaultList.add(q);
            });
            Map<Long , List<QuesRecordVo>> q_map = BeanUtils.toGroup(defaultList , "examModelBlockId");
            blocks.forEach(b -> {
                ExamModelBlockRecordVo blockRecordVo = new ExamModelBlockRecordVo();
                DefindBeanUtils.copyProperties(b , blockRecordVo);
                blockRecordVo.setList(q_map.get(b.getId()));
                list.add(blockRecordVo);
            });
            s.setRecordStatus(0);
        }
        s.setIsChanged(1);
        s.setList(list);
        s.setStuId(stuId);
        return s;
    }
}
